<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Kylin</title><meta name="keywords" content="学习，博客，技术交流，学习记录，Kylin，kylin"><meta name="author" content="Kylin"><meta name="copyright" content="Kylin"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="学习不易，努力努力~">
<meta property="og:type" content="website">
<meta property="og:title" content="Kylin">
<meta property="og:url" content="https://www.codekylin.cn/index.html">
<meta property="og:site_name" content="Kylin">
<meta property="og:description" content="学习不易，努力努力~">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://qiniu.codekylin.cn/img/20200807181526.jpg">
<meta property="article:author" content="Kylin">
<meta property="article:tag" content="学习，博客，技术交流，学习记录，Kylin，kylin">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://qiniu.codekylin.cn/img/20200807181526.jpg"><link rel="shortcut icon" href="https://qiniu.codekylin.cn/img/20200807181548.png"><link rel="canonical" href="https://www.codekylin.cn/"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//www.google-analytics.com" crossorigin=""/><link rel="preconnect" href="//hm.baidu.com"/><link rel="preconnect" href="//fonts.googleapis.com" crossorigin=""/><meta name="google-site-verification" content="gzeyWstt6NoTZKh7YFYNLNziL8HIZ8YH2Ug7xTDX5-Y"/><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.css" media="print" onload="this.media='all'"><script>var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?f76c34daefe747deee7c7be3ead2ba80";
  var s = document.getElementsByTagName("script")[0]; 
  s.parentNode.insertBefore(hm, s);
})();
</script><script async="async" src="https://www.googletagmanager.com/gtag/js?id=UA-159334016-1"></script><script>window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-159334016-1');
</script><link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Titillium+Web" media="print" onload="this.media='all'"><script>const GLOBAL_CONFIG = { 
  root: '/',
  algolia: undefined,
  localSearch: {"path":"search.xml","languages":{"hits_empty":"找不到您查询的内容：${query}"}},
  translate: {"defaultEncoding":2,"translateDelay":0,"msgToTraditionalChinese":"繁","msgToSimplifiedChinese":"简"},
  noticeOutdate: {"limitDay":90,"position":"top","messagePrev":"自上次更新以来已经","messageNext":"天，文章的内容可能已过时或存在差异。"},
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":false},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: false,
    post: false
  },
  runtime: '天',
  date_suffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: {"limitCount":50000,"languages":{"author":"作者: Kylin","link":"链接: ","source":"来源: Kylin","info":"著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。"}},
  lightbox: 'fancybox',
  Snackbar: {"chs_to_cht":"你已切换为繁体","cht_to_chs":"你已切换为简体","day_to_night":"你已切换为深色模式","night_to_day":"你已切换为浅色模式","bgLight":"#FF0000","bgDark":"#2d3035","position":"bottom-left"},
  source: {
    jQuery: 'https://cdn.jsdelivr.net/npm/jquery@latest/dist/jquery.min.js',
    justifiedGallery: {
      js: 'https://cdn.jsdelivr.net/npm/justifiedGallery/dist/js/jquery.justifiedGallery.min.js',
      css: 'https://cdn.jsdelivr.net/npm/justifiedGallery/dist/css/justifiedGallery.min.css'
    },
    fancybox: {
      js: 'https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@latest/dist/jquery.fancybox.min.js',
      css: 'https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@latest/dist/jquery.fancybox.min.css'
    }
  },
  isPhotoFigcaption: false,
  islazyload: true,
  isanchor: false
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = { 
  isPost: false,
  isHome: true,
  isHighlightShrink: false,
  isToc: false,
  postUpdate: '2022-10-12 21:14:27'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(win=>{
    win.saveToLocal = {
      set: function setWithExpiry(key, value, ttl) {
        if (ttl === 0) return
        const now = new Date()
        const expiryDay = ttl * 86400000
        const item = {
          value: value,
          expiry: now.getTime() + expiryDay,
        }
        localStorage.setItem(key, JSON.stringify(item))
      },

      get: function getWithExpiry(key) {
        const itemStr = localStorage.getItem(key)

        if (!itemStr) {
          return undefined
        }
        const item = JSON.parse(itemStr)
        const now = new Date()

        if (now.getTime() > item.expiry) {
          localStorage.removeItem(key)
          return undefined
        }
        return item.value
      }
    }
  
    win.getScript = url => new Promise((resolve, reject) => {
      const script = document.createElement('script')
      script.src = url
      script.async = true
      script.onerror = reject
      script.onload = script.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        script.onload = script.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(script)
    })
  
      win.activateDarkMode = function () {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = function () {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
          const isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches
          const isLightMode = window.matchMedia('(prefers-color-scheme: light)').matches
          const isNotSpecified = window.matchMedia('(prefers-color-scheme: no-preference)').matches
          const hasNoSupport = !isDarkMode && !isLightMode && !isNotSpecified

          if (t === undefined) {
            if (isLightMode) activateLightMode()
            else if (isDarkMode) activateDarkMode()
            else if (isNotSpecified || hasNoSupport) {
              const now = new Date()
              const hour = now.getHours()
              const isNight = hour <= 6 || hour >= 18
              isNight ? activateDarkMode() : activateLightMode()
            }
            window.matchMedia('(prefers-color-scheme: dark)').addListener(function (e) {
              if (saveToLocal.get('theme') === undefined) {
                e.matches ? activateDarkMode() : activateLightMode()
              }
            })
          } else if (t === 'light') activateLightMode()
          else activateDarkMode()
        
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
    const fontSizeVal = saveToLocal.get('global-font-size')
    if (fontSizeVal !== undefined) {
      document.documentElement.style.setProperty('--global-font-size', fontSizeVal + 'px')
    }
    })(window)</script><link rel="stylesheet" href="https://qiniu.codekylin.cn/github/img/img/custom.css"><link rel="stylesheet" href="//at.alicdn.com/t/font_1993646_z05rabxf05h.css"><link rel="stylesheet" href="https://qiniu.codekylin.cn/github/img/img/icon.css"><meta name="generator" content="Hexo 5.4.0"><link rel="alternate" href="/atom.xml" title="Kylin" type="application/atom+xml">
</head><body><div id="web_bg"></div><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="author-avatar"><img class="avatar-img" data-lazy-src="https://qiniu.codekylin.cn/img/20200807181526.jpg" onerror="onerror=null;src='https://qiniu.codekylin.cn/github/img/friend_404.gif'" alt="avatar"/></div><div class="site-data"><div class="data-item is-center"><div class="data-item-link"><a href="/archives/"><div class="headline">文章</div><div class="length-num">362</div></a></div></div><div class="data-item is-center"><div class="data-item-link"><a href="/tags/"><div class="headline">标签</div><div class="length-num">427</div></a></div></div><div class="data-item is-center"><div class="data-item-link"><a href="/categories/"><div class="headline">分类</div><div class="length-num">101</div></a></div></div></div><hr/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fa fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fa fa-archive"></i><span> 时间轴</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fa fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fa fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fa fa-link"></i><span> 友链</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fa fa-heart"></i><span> 关于</span></a></div></div></div></div><div class="page" id="body-wrap"><header class="full_page" id="page-header" style="background-image: url('https://qiniu.codekylin.cn/github/img/img20201017211426.jpg')"><nav id="nav"><span id="blog_name"><a id="site-name" href="/">Kylin</a></span><div id="menus"><div id="search-button"><a class="site-page social-icon search"><i class="fas fa-search fa-fw"></i><span> 搜索</span></a></div><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fa fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fa fa-archive"></i><span> 时间轴</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fa fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fa fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fa fa-link"></i><span> 友链</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fa fa-heart"></i><span> 关于</span></a></div></div><div id="toggle-menu"><a class="site-page"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="site-info"><h1 id="site-title">Kylin</h1><div id="site-subtitle"><span id="subtitle"></span></div><div id="site_social_icons"><a class="social-icon" href="https://github.com/kylincw" target="_blank" title="Github"><i class="iconfont icon-github"></i></a><a class="social-icon" href="tencent://message/?Menu=yes&amp;uin=171346168&amp;Service=300&amp;sigT=45a1e5847943b64c6ff3990f8a9e644d2b31356cb0b4ac6b24663a3c8dd0f8aa12a595b1714f9d45" target="_blank" title="qq"><i class="iconfont icon-qq"></i></a><a class="social-icon" href="https://space.bilibili.com/53836035" target="_blank" title="BiliBili"><i class="iconfont icon-bilibili-line"></i></a><a class="social-icon" href="mailto:zhang171346168@qq.com" target="_blank" title="Email"><i class="iconfont icon-email1"></i></a><a class="social-icon" href="/atom.xml" target="_blank" title="RSS"><i class="iconfont icon-rss"></i></a></div></div><div id="scroll-down"><i class="fas fa-angle-down scroll-down-effects"></i></div></header><main class="layout" id="content-inner"><div class="recent-posts" id="recent-posts"><div class="recent-post-item"><div class="post_cover left_radius"><a href="/44452.html" title="GitHub OAuth第三方登录">     <img class="post_bg" data-lazy-src="https://qiniu.codekylin.cn/github/img/img/code1.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="GitHub OAuth第三方登录"></a></div><div class="recent-post-info"><a class="article-title" href="/44452.html" title="GitHub OAuth第三方登录">GitHub OAuth第三方登录</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">发表于</span><time datetime="2022-03-04T11:09:36.000Z" title="发表于 2022-03-04 19:09:36">2022-03-04</time></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/OAuth/">OAuth</a></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-comments"></i><a href="/44452.html#post-comment" itemprop="discussionUrl"><span class="valine-comment-count" data-xid="/44452.html" itemprop="commentCount"></span></a><span class="article-meta-label"> 条评论</span></span></div><div class="content">
GitHub OAuth 第三方登录示例教程 - 阮一峰的网络日志 (ruanyifeng.com)

概述前面介绍了OAuth的详细概念知识。很多网站登录时，允许使用第三方网站的身份，这称为”第三方登录”。

下面就以 GitHub 为例，写一个最简单的应用，演示第三方登录。
第三方登录的原理所谓第三方登录，实质就是 OAuth 授权。用户想要登录 A 网站，A 网站让用户提供第三方网站的数据，证明自己的身份。获取第三方网站的身份数据，就需要 OAuth 授权。
举例来说，A 网站允许 GitHub 登录，背后就是下面的流程。

A 网站让用户跳转到 GitHub。
GitHub 要求用户登录，然后询问”A 网站要求获得 xx 权限，你是否同意？”
用户同意，GitHub 就会重定向回 A 网站，同时发回一个授权码。
A 网站使用授权码，向 GitHub 请求令牌。
GitHub 返回令牌.
A 网站使用令牌，向 GitHub 请求用户数据。

应用登记一个应用要求 OAuth 授权，必须先到对方网站登记，让对方知道是谁在请求。
所以，你要先去 GitHub 登记一下。当然，我已经 ...</div></div></div><div class="recent-post-item"><div class="post_cover right_radius"><a href="/263.html" title="OAuth2.0的四种授权">     <img class="post_bg" data-lazy-src="https://qiniu.codekylin.cn/github/img/img/wallhaven-4x28xo.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="OAuth2.0的四种授权"></a></div><div class="recent-post-info"><a class="article-title" href="/263.html" title="OAuth2.0的四种授权">OAuth2.0的四种授权</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">发表于</span><time datetime="2022-03-04T10:18:25.000Z" title="发表于 2022-03-04 18:18:25">2022-03-04</time></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/OAuth/">OAuth</a></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-comments"></i><a href="/263.html#post-comment" itemprop="discussionUrl"><span class="valine-comment-count" data-xid="/263.html" itemprop="commentCount"></span></a><span class="article-meta-label"> 条评论</span></span></div><div class="content">
OAuth 2.0 的四种方式 - 阮一峰的网络日志 (ruanyifeng.com)
10 分钟理解什么是 OAuth 2.0 协议 | Deepzz’s Blog

概述OAuth 2.0 的标准是 RFC 6749 文件。该文件先解释了 OAuth 是什么。

OAuth 引入了一个授权层，用来分离两种不同的角色：客户端和资源所有者。……资源所有者同意以后，资源服务器可以向客户端颁发令牌。客户端通过令牌，去请求数据。

这段话的意思就是，OAuth 的核心就是向第三方应用颁发令牌。然后，RFC 6749 接着写道：

（由于互联网有多种场景，）本标准定义了获得令牌的四种授权方式（authorization grant ）。

OAuth 2.0 列举了四种授权类型，分别用于不同的场景：

Authorization Code（授权码 code）：服务器与客户端配合使用。
Implicit（隐式 token）：用于移动应用程序或 Web 应用程序（在用户设备上运行的应用程序）。
Resource Owner Password Credentials（资源所有者密码凭证 passw ...</div></div></div><div class="recent-post-item"><div class="post_cover left_radius"><a href="/64258.html" title="什么是OAuth2.0?">     <img class="post_bg" data-lazy-src="https://qiniu.codekylin.cn/img/20200418115059.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="什么是OAuth2.0?"></a></div><div class="recent-post-info"><a class="article-title" href="/64258.html" title="什么是OAuth2.0?">什么是OAuth2.0?</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">发表于</span><time datetime="2022-03-04T10:02:47.000Z" title="发表于 2022-03-04 18:02:47">2022-03-04</time></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/OAuth/">OAuth</a></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-comments"></i><a href="/64258.html#post-comment" itemprop="discussionUrl"><span class="valine-comment-count" data-xid="/64258.html" itemprop="commentCount"></span></a><span class="article-meta-label"> 条评论</span></span></div><div class="content">
OAuth 2.0 的一个简单解释 - 阮一峰的网络日志 (ruanyifeng.com)
认证授权基础 | JavaGuide

概述OAuth 是一个行业的标准授权协议，主要用来授权第三方应用获取有限的权限。而 OAuth 2.0 是对 OAuth 1.0 的完全重新设计，OAuth 2.0 更快，更容易实现，OAuth 1.0 已经被废弃。详情请见：rfc6749  (opens new window)。
实际上它就是一种授权机制，它的最终目的是为第三方应用颁发一个有时效性的令牌 Token，使得第三方应用能够通过该令牌获取相关的资源。
OAuth 2.0 比较常用的场景就是第三方登录，当你的网站接入了第三方登录的时候一般就是使用的 OAuth 2.0 协议。
另外，现在 OAuth 2.0 也常见于支付场景（微信支付、支付宝支付）和开发平台（微信开放平台、阿里开放平台等等）。
微信支付账户相关参数：

下图是 Slack OAuth 2.0 第三方登录 (opens new window)的示意图：

角色首先需要介绍的是 OAuth 2.0 协议中的一些角色，整个授权协议的 ...</div></div></div><div class="recent-post-item"><div class="post_cover right_radius"><a href="/41745.html" title="Transactional注解的6种失效场景">     <img class="post_bg" data-lazy-src="https://qiniu.codekylin.cn/github/images/20200418114518.png" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="Transactional注解的6种失效场景"></a></div><div class="recent-post-info"><a class="article-title" href="/41745.html" title="Transactional注解的6种失效场景">Transactional注解的6种失效场景</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">发表于</span><time datetime="2022-03-02T13:56:30.000Z" title="发表于 2022-03-02 21:56:30">2022-03-02</time></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/Spring/">Spring</a></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-comments"></i><a href="/41745.html#post-comment" itemprop="discussionUrl"><span class="valine-comment-count" data-xid="/41745.html" itemprop="commentCount"></span></a><span class="article-meta-label"> 条评论</span></span></div><div class="content">
一口气说出 6种 @Transactional 注解失效场景 (qq.com)

@Transactional@Transactional 可以作用在接口、类、类方法。

作用于类：当把@Transactional 注解放在类上时，表示所有该类的public方法都配置相同的事务属性信息。
作用于方法：当类配置了@Transactional，方法也配置了@Transactional，方法的事务会覆盖类的事务配置信息。
作用于接口：不推荐这种使用方法，因为一旦标注在Interface上并且配置了Spring AOP 使用CGLib动态代理，将会导致@Transactional注解失效。

相关属性Spring事务详解 | Kylin (codekylin.cn)
@Transactional 应用在非 public 修饰的方法上如果Transactional注解应用在非public 修饰的方法上，Transactional将会失效。

之所以会失效是因为在Spring AOP 代理时，如上图所示 TransactionInterceptor （事务拦截器）在目标方法执行前后进行拦截，Dy ...</div></div></div><div class="recent-post-item"><div class="post_cover left_radius"><a href="/43689.html" title="Jenkins构建项目">     <img class="post_bg" data-lazy-src="https://qiniu.codekylin.cn/img/20200418114719.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="Jenkins构建项目"></a></div><div class="recent-post-info"><a class="article-title" href="/43689.html" title="Jenkins构建项目">Jenkins构建项目</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">发表于</span><time datetime="2022-02-11T08:20:32.000Z" title="发表于 2022-02-11 16:20:32">2022-02-11</time></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/Jenkins/">Jenkins</a></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-comments"></i><a href="/43689.html#post-comment" itemprop="discussionUrl"><span class="valine-comment-count" data-xid="/43689.html" itemprop="commentCount"></span></a><span class="article-meta-label"> 条评论</span></span></div><div class="content">Jenkins中自动构建项目的类型有很多，常用的有以下三种： 

自由风格软件项目（FreeStyle Project） 
Maven项目（Maven Project） 
流水线项目（Pipeline Project）

每种类型的构建其实都可以完成一样的构建过程与结果，只是在操作方式、灵活度等方面有所区别，在实际开发中可以根据自己的需求和习惯来选择。（PS：个人推荐使用流水线类型，因为灵活度非常高）
自由风格项目构建
配置源码管理，从gitlab拉取代码

构建-&gt;添加构建步骤-&gt;Executor Shell

123echo &quot;开始编译和打包&quot;mvn clean packageecho &quot;编译和打包结束&quot;

把项目部署到远程的Tomcat里面。
Jenkins本身无法实现远程部署到Tomcat的功能，需要安装Deploy to container插件实现

下载安装成功后，重启Jenkins。接着创建Tomcat用户密码凭证

接着回到我们的项目配置里构建后操作—&gt;Deploy war/ear to a container
 ...</div></div></div><div class="recent-post-item"><div class="post_cover right_radius"><a href="/34480.html" title="Jenkins自动部署环境准备">     <img class="post_bg" data-lazy-src="https://qiniu.codekylin.cn/github/images/20200418114518.png" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="Jenkins自动部署环境准备"></a></div><div class="recent-post-info"><a class="article-title" href="/34480.html" title="Jenkins自动部署环境准备">Jenkins自动部署环境准备</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">发表于</span><time datetime="2022-02-11T07:39:34.000Z" title="发表于 2022-02-11 15:39:34">2022-02-11</time></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/Jenkins/">Jenkins</a></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-comments"></i><a href="/34480.html#post-comment" itemprop="discussionUrl"><span class="valine-comment-count" data-xid="/34480.html" itemprop="commentCount"></span></a><span class="article-meta-label"> 条评论</span></span></div><div class="content">Maven安装和配置安装在Jenkins集成服务器上，我们需要安装Maven来编译和打包项目。
下载apache-maven-3.6.3-bin.tar.gz。上传到/usr/local/
12tar -zxvf apache-maven-3.6.3-bin.tar.gzvim /etc/profile


source /etc/profile
mvn -v查看Maven版本

安装成功！
全局工具配置关联JDK和MavenJenkins-&gt;Global Tool Configuration-&gt;JDK-&gt;新增JDK，配置如下：


Jenkins-&gt;Global Tool Configuration-&gt;Maven-&gt;新增Maven，配置如下：

添加Jenkins全局变量 Manage Jenkins-&gt;Configure System-&gt;Global Properties ，添加三个全局变量 

JAVA_HOME
M2_HOME
PATH+EXTRA


配置文件12mkdir /repositoryvim /usr/local/a ...</div></div></div><div class="recent-post-item"><div class="post_cover left_radius"><a href="/10464.html" title="Jenkins安装和插件使用">     <img class="post_bg" data-lazy-src="https://qiniu.codekylin.cn/img/20200418114651.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="Jenkins安装和插件使用"></a></div><div class="recent-post-info"><a class="article-title" href="/10464.html" title="Jenkins安装和插件使用">Jenkins安装和插件使用</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">发表于</span><time datetime="2022-02-11T07:33:44.000Z" title="发表于 2022-02-11 15:33:44">2022-02-11</time></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/Jenkins/">Jenkins</a></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-comments"></i><a href="/10464.html#post-comment" itemprop="discussionUrl"><span class="valine-comment-count" data-xid="/10464.html" itemprop="commentCount"></span></a><span class="article-meta-label"> 条评论</span></span></div><div class="content">安装安装JDK
获取jenkins安装包
下载页面：https://jenkins.io/zh/download/ 
安装文件：jenkins-2.190.3-1.1.noarch.rpm

rpm -ivh jenkins-2.190.3-1.1.noarch.rpm命令安装

修改Jenkins配置
vi /etc/syscofig/jenkins
修改内容如下：
12JENKINS_USER=&quot;root&quot; JENKINS_PORT=&quot;8888&quot;


将用户改成root否则默认使用的是jenkins用户，则需要创建一个Linux用户。
启动Jenkins
systemctl start jenkins
出现问题Jenkins bash: /usr/bin/java: No such file or directory
vim /etc/init.d/jenkins编辑文件，将candidates加入自己配置的JAVA_HOME的bin下的java命令

再次启动Jenkins 
systemctl start jenkins

cat /va ...</div></div></div><div class="recent-post-item"><div class="post_cover right_radius"><a href="/29138.html" title="GitLab的安装使用">     <img class="post_bg" data-lazy-src="https://qiniu.codekylin.cn/github/img/img/wallhaven-2k8wlg.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="GitLab的安装使用"></a></div><div class="recent-post-info"><a class="article-title" href="/29138.html" title="GitLab的安装使用">GitLab的安装使用</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">发表于</span><time datetime="2022-02-11T07:25:20.000Z" title="发表于 2022-02-11 15:25:20">2022-02-11</time></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-comments"></i><a href="/29138.html#post-comment" itemprop="discussionUrl"><span class="valine-comment-count" data-xid="/29138.html" itemprop="commentCount"></span></a><span class="article-meta-label"> 条评论</span></span></div><div class="content">概念
GitLab是一个利用 Ruby on Rails 开发的开源应用程序，实现一个自托管的Git项目仓库，可通过Web界面进行访问公开的或者私人项目。
安装yum -y install policycoreutils openssh-server openssh-clients postfix

systemctl enable sshd &amp;&amp; sudo systemctl start sshd
systemctl enable postfix &amp;&amp; systemctl start postfix
wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el6/gitlab-ce-12.4.2-ce.0.el6.x86_64.rpm
命令运行失败，点击链接下载，上传到服务器即可。
安装
rpm -ivh gitlab-ce-12.4.2-ce.0.el6.x86_64.rpm
rpm -ivh --replacepkgs gitlab-ce-12.4.2-ce.0.el6.x86_64.rpm覆 ...</div></div></div><div class="recent-post-item"><div class="post_cover left_radius"><a href="/47602.html" title="超详细的Vagrant上手指南">     <img class="post_bg" data-lazy-src="https://qiniu.codekylin.cn/img/20200418114719.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="超详细的Vagrant上手指南"></a></div><div class="recent-post-info"><a class="article-title" href="/47602.html" title="超详细的Vagrant上手指南">超详细的Vagrant上手指南</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">发表于</span><time datetime="2022-01-30T02:35:56.000Z" title="发表于 2022-01-30 10:35:56">2022-01-30</time></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/vagrant/">vagrant</a></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-comments"></i><a href="/47602.html#post-comment" itemprop="discussionUrl"><span class="valine-comment-count" data-xid="/47602.html" itemprop="commentCount"></span></a><span class="article-meta-label"> 条评论</span></span></div><div class="content">
本文转载https://zhuanlan.zhihu.com/p/259833884

搭建 Linux 虚拟机，别再用 VirtualBox 从 .iso 文件安装了。
概述2020 年了，也许你已经习惯了 docker，习惯了在 XX 云上快速创建云主机，但是如果你想在个人电脑上安装虚拟机来搭建开发/测试环境，Vagrant 仍然不失高效之选。

文末有和 docker 的对比说明。

本篇内容字数过万，收藏的同时别忘了点个赞，谢谢！
安装软件安装 VirtualBox
进入 VirtualBox 的主页，点击大大的下载按钮，即可进入下载页面。
VirtualBox 是一个跨平台的虚拟化工具，支持多个操作系统，根据自己的情况选择对应的版本下载即可。
注意，除了主程序，还要把对应的扩展包程序也一并下载了。有些高级特性，比如 USB 3.0 等需要扩展包的支持。

在安装完主程序后，直接双击扩展包文件即可安装扩展包。

下载页面先别关，后面还要用到。

安装 Vagrant
在 Vagant 网站下载最新的版本，根据自己的操作系统选择对应的版本下载即可。
注意，Vagrant 是没有 ...</div></div></div><div class="recent-post-item"><div class="post_cover right_radius"><a href="/45434.html" title="Docker监控CIG">     <img class="post_bg" data-lazy-src="https://qiniu.codekylin.cn/github/img/img/wallhaven-3kp6yv.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="Docker监控CIG"></a></div><div class="recent-post-info"><a class="article-title" href="/45434.html" title="Docker监控CIG">Docker监控CIG</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">发表于</span><time datetime="2022-01-29T11:54:55.000Z" title="发表于 2022-01-29 19:54:55">2022-01-29</time></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/Docker/">Docker</a><i class="fas fa-angle-right"></i><a class="article-meta__categories" href="/categories/Docker/CIG/">CIG</a></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-comments"></i><a href="/45434.html#post-comment" itemprop="discussionUrl"><span class="valine-comment-count" data-xid="/45434.html" itemprop="commentCount"></span></a><span class="article-meta-label"> 条评论</span></span></div><div class="content">概念通过docker stats命令可以很方便的看到当前宿主机上所有容器的CPU,内存以及网络流量等数据，一般小公司够用了。。。。

但是，docker stats统计结果只能是当前宿主机的全部容器，数据资料是实时的，没有地方存储、没有健康指标过线预警等功能
CAdvisorCAdvisor是一个容器资源监控工具，包括容器的内存，CPU，网络IO，磁盘IO等监控，同时提供了一个WEB页面用于查看容器的实时运行状态。CAdvisor默认存储2分钟的数据，而且只是针对单物理机。不过，CAdvisor提供了很多数据集成接口，支持InfluxDB，Redis，Kafka，Elasticsearch等集成，可以加上对应配置将监控数据发往这些数据库存储起来。
功能主要有两点：

展示Host和容器两个层次的监控数据
展示历史变化数据

InfluxDBInfluxDB是一种时序数据库，用来存放监控数据。InfluxDB 是用Go语言编写的一个开源分布式时序、事件和指标数据库，无需外部依赖。
CAdvisor默认只在本机保存最近2分钟的数据，为了持久化存储数据和统一收集展示监控数据，需要将数据存储到 ...</div></div></div><nav id="pagination"><div class="pagination"><span class="page-number current">1</span><a class="page-number" href="/page/2/#content-inner">2</a><span class="space">&hellip;</span><a class="page-number" href="/page/37/#content-inner">37</a><a class="extend next" rel="next" href="/page/2/#content-inner"><i class="fas fa-chevron-right fa-fw"></i></a></div></nav></div><div class="aside-content" id="aside-content"><div class="card-widget card-info"><div class="card-info-avatar is-center"><img class="avatar-img" data-lazy-src="https://qiniu.codekylin.cn/img/20200807181526.jpg" onerror="this.onerror=null;this.src='https://qiniu.codekylin.cn/github/img/friend_404.gif'" alt="avatar"/><div class="author-info__name">Kylin</div><div class="author-info__description">学习不易，努力努力~</div></div><div class="card-info-data"><div class="card-info-data-item is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">362</div></a></div><div class="card-info-data-item is-center"><a href="/tags/"><div class="headline">标签</div><div class="length-num">427</div></a></div><div class="card-info-data-item is-center"><a href="/categories/"><div class="headline">分类</div><div class="length-num">101</div></a></div></div><a class="button--animated" id="card-info-btn"><i class="fas fa-bookmark"></i><span>加入书签</span></a><div class="card-info-social-icons is-center"><a class="social-icon" href="https://github.com/kylincw" target="_blank" title="Github"><i class="iconfont icon-github"></i></a><a class="social-icon" href="tencent://message/?Menu=yes&amp;uin=171346168&amp;Service=300&amp;sigT=45a1e5847943b64c6ff3990f8a9e644d2b31356cb0b4ac6b24663a3c8dd0f8aa12a595b1714f9d45" target="_blank" title="qq"><i class="iconfont icon-qq"></i></a><a class="social-icon" href="https://space.bilibili.com/53836035" target="_blank" title="BiliBili"><i class="iconfont icon-bilibili-line"></i></a><a class="social-icon" href="mailto:zhang171346168@qq.com" target="_blank" title="Email"><i class="iconfont icon-email1"></i></a><a class="social-icon" href="/atom.xml" target="_blank" title="RSS"><i class="iconfont icon-rss"></i></a></div></div><div class="card-widget card-announcement"><div class="item-headline"><i class="fas fa-bullhorn card-announcement-animation"></i><span>公告</span></div><div class="announcement_content">学习不易，努力努力！</div></div><div class="sticky_layout"><div class="card-widget card-recent-post"><div class="item-headline"><i class="fas fa-history"></i><span>最新文章</span></div><div class="aside-list"><div class="aside-list-item"><a class="thumbnail" href="/56352.html" title="be动词"><img data-lazy-src="https://qiniu.codekylin.cn/github/img/img/博客封面10.png" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="be动词"/></a><div class="content"><a class="title" href="/56352.html" title="be动词">be动词</a><time datetime="2022-07-12T11:47:29.800Z" title="更新于 2022-07-12 19:47:29">2022-07-12</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/36436.html" title="JVM堆内存"><img data-lazy-src="https://qiniu.codekylin.cn/img/20200418115059.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="JVM堆内存"/></a><div class="content"><a class="title" href="/36436.html" title="JVM堆内存">JVM堆内存</a><time datetime="2022-07-12T11:47:29.800Z" title="更新于 2022-07-12 19:47:29">2022-07-12</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/44292.html" title="Java多线程详解"><img data-lazy-src="https://qiniu.codekylin.cn/github/img/img/wallhaven-eorjzk.png" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="Java多线程详解"/></a><div class="content"><a class="title" href="/44292.html" title="Java多线程详解">Java多线程详解</a><time datetime="2022-07-12T11:47:29.800Z" title="更新于 2022-07-12 19:47:29">2022-07-12</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/40200.html" title="谷粒商城记录"><img data-lazy-src="https://qiniu.codekylin.cn/github/img/img/wallhaven-6qvvrx.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="谷粒商城记录"/></a><div class="content"><a class="title" href="/40200.html" title="谷粒商城记录">谷粒商城记录</a><time datetime="2022-07-12T11:47:29.800Z" title="更新于 2022-07-12 19:47:29">2022-07-12</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/27082.html" title="Spring学习-3"><img data-lazy-src="https://qiniu.codekylin.cn/github/img/img/wallhaven-4x28xo.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="Spring学习-3"/></a><div class="content"><a class="title" href="/27082.html" title="Spring学习-3">Spring学习-3</a><time datetime="2022-07-12T11:47:29.799Z" title="更新于 2022-07-12 19:47:29">2022-07-12</time></div></div></div></div><div class="card-widget" id="card-newest-comments"><div class="item-headline"><i class="fas fa-bolt"></i><span>最新评论</span></div><div class="aside-list"><span>正在加载中...</span></div></div><div class="card-widget card-categories"><div class="item-headline">
            <i class="fas fa-folder-open"></i>
            <span>分类</span>
            <a class="card-more-btn" href="/categories/" title="查看更多">
    <i class="fas fa-angle-right"></i></a>
            </div>
            <ul class="card-category-list" id="aside-cat-list">
            <li class="card-category-list-item parent"><a class="card-category-list-link" href="/categories/Docker/"><span class="card-category-list-name">Docker</span><span class="card-category-list-count">8</span><i class="fas fa-caret-left "></i></a><ul class="card-category-list child"><li class="card-category-list-item "><a class="card-category-list-link" href="/categories/Docker/CIG/"><span class="card-category-list-name">CIG</span><span class="card-category-list-count">1</span></a></li><li class="card-category-list-item "><a class="card-category-list-link" href="/categories/Docker/compose/"><span class="card-category-list-name">compose</span><span class="card-category-list-count">1</span></a></li></ul></li><li class="card-category-list-item "><a class="card-category-list-link" href="/categories/Elasticsearch/"><span class="card-category-list-name">Elasticsearch</span><span class="card-category-list-count">5</span></a></li><li class="card-category-list-item "><a class="card-category-list-link" href="/categories/English/"><span class="card-category-list-name">English</span><span class="card-category-list-count">1</span></a></li><li class="card-category-list-item parent"><a class="card-category-list-link" href="/categories/Java/"><span class="card-category-list-name">Java</span><span class="card-category-list-count">69</span><i class="fas fa-caret-left "></i></a><ul class="card-category-list child"><li class="card-category-list-item "><a class="card-category-list-link" href="/categories/Java/IO%E6%B5%81/"><span class="card-category-list-name">IO流</span><span class="card-category-list-count">10</span></a></li><li class="card-category-list-item "><a class="card-category-list-link" href="/categories/Java/JDBC/"><span class="card-category-list-name">JDBC</span><span class="card-category-list-count">5</span></a></li></ul></li>
            </ul></div><div class="card-widget card-tags"><div class="item-headline"><i class="fas fa-tags"></i><span>标签</span></div><div class="card-tag-cloud"><a href="/tags/ajax/" style="font-size: 1.15em; color: rgb(29, 46, 14)">ajax</a><a href="/tags/SpringBoot/" style="font-size: 1.45em; color: rgb(40, 91, 26)">SpringBoot</a><a href="/tags/Docker/" style="font-size: 1.3em; color: rgb(68, 166, 82)">Docker</a><a href="/tags/Dockerfile/" style="font-size: 1.15em; color: rgb(1, 93, 85)">Dockerfile</a><a href="/tags/%E5%AE%89%E8%A3%85/" style="font-size: 1.15em; color: rgb(194, 55, 83)">安装</a><a href="/tags/%E5%8D%B8%E8%BD%BD/" style="font-size: 1.15em; color: rgb(43, 190, 86)">卸载</a><a href="/tags/Docker%E7%9A%84%E4%BD%BF%E7%94%A8/" style="font-size: 1.15em; color: rgb(98, 192, 42)">Docker的使用</a><a href="/tags/Portainer/" style="font-size: 1.15em; color: rgb(180, 104, 53)">Portainer</a><a href="/tags/ES6/" style="font-size: 1.15em; color: rgb(185, 98, 89)">ES6</a><a href="/tags/%E7%AE%AD%E5%A4%B4%E5%87%BD%E6%95%B0/" style="font-size: 1.15em; color: rgb(135, 130, 156)">箭头函数</a></div></div><div class="card-widget card-archives"><div class="item-headline"><i class="fas fa-archive"></i><span>归档</span><a class="card-more-btn" href="/archives/" title="查看更多">
    <i class="fas fa-angle-right"></i></a></div><ul class="card-archive-list"><li class="card-archive-list-item"><a class="card-archive-list-link" href="/archives/2022/03/"><span class="card-archive-list-date">2022年03月</span><span class="card-archive-list-count">4</span></a></li><li class="card-archive-list-item"><a class="card-archive-list-link" href="/archives/2022/02/"><span class="card-archive-list-date">2022年02月</span><span class="card-archive-list-count">4</span></a></li><li class="card-archive-list-item"><a class="card-archive-list-link" href="/archives/2022/01/"><span class="card-archive-list-date">2022年01月</span><span class="card-archive-list-count">11</span></a></li><li class="card-archive-list-item"><a class="card-archive-list-link" href="/archives/2021/12/"><span class="card-archive-list-date">2021年12月</span><span class="card-archive-list-count">4</span></a></li><li class="card-archive-list-item"><a class="card-archive-list-link" href="/archives/2021/11/"><span class="card-archive-list-date">2021年11月</span><span class="card-archive-list-count">3</span></a></li><li class="card-archive-list-item"><a class="card-archive-list-link" href="/archives/2021/06/"><span class="card-archive-list-date">2021年06月</span><span class="card-archive-list-count">5</span></a></li><li class="card-archive-list-item"><a class="card-archive-list-link" href="/archives/2021/05/"><span class="card-archive-list-date">2021年05月</span><span class="card-archive-list-count">2</span></a></li><li class="card-archive-list-item"><a class="card-archive-list-link" href="/archives/2021/03/"><span class="card-archive-list-date">2021年03月</span><span class="card-archive-list-count">4</span></a></li></ul></div><div class="card-widget card-webinfo"><div class="item-headline"><i class="fas fa-chart-line"></i><span>网站资讯</span></div><div class="webinfo"><div class="webinfo-item"><div class="item-name">文章数目 :</div><div class="item-count">362</div></div><div class="webinfo-item"><div class="item-name">已运行时间 :</div><div class="item-count" id="runtimeshow" data-publishDate="2019-08-01T16:00:00.000Z"></div></div><div class="webinfo-item"><div class="item-name">本站总字数 :</div><div class="item-count">539.1k</div></div><div class="webinfo-item"><div class="item-name">最后更新时间 :</div><div class="item-count" id="last-push-date" data-lastPushDate="2022-10-12T13:14:25.092Z"></div></div></div></div></div></div></main><footer id="footer" style="background-image: url('https://qiniu.codekylin.cn/github/img/img20201017211426.jpg')"><div id="footer-wrap"><div class="copyright">&copy;2019 - 2022 By Kylin</div><div class="framework-info"><span>框架 </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div><div class="footer_custom_text"><a target="_blank" rel="noopener" href="https://beian.miit.gov.cn/"><img class="icp-icon" src="https://img.alicdn.com/tfs/TB1..50QpXXXXX7XpXXXXXXXXXX-40-40.png"><span>湘ICP备2022005420号-1</span></a></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="font-plus" type="button" title="放大字体"><i class="fas fa-plus"></i></button><button id="font-minus" type="button" title="缩小字体"><i class="fas fa-minus"></i></button><button id="translateLink" type="button" title="简繁转换">繁</button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button id="go-up" type="button" title="回到顶部"><i class="fas fa-arrow-up"></i></button></div></div><div id="local-search"><div class="search-dialog"><div class="search-dialog__title" id="local-search-title">本地搜索</div><div id="local-input-panel"><div id="local-search-input"><div class="local-search-box"><input class="local-search-box--input" placeholder="搜索文章" type="text"/></div></div></div><hr/><div id="local-search-results"></div><span class="search-close-button"><i class="fas fa-times"></i></span></div><div id="search-mask"></div></div><div><script src="/js/utils.js"></script><script src="/js/main.js"></script><script src="/js/tw_cn.js"></script><script src="https://cdn.jsdelivr.net/npm/instant.page/instantpage.min.js" type="module"></script><script src="https://cdn.jsdelivr.net/npm/vanilla-lazyload/dist/lazyload.iife.min.js"></script><script src="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.js"></script><script src="/js/search/local-search.js"></script><div class="js-pjax"><script>(() => {
  function loadValine () {
    function initValine () {
      let initData = {
        el: '#vcomment',
        appId: 'ClIyIUhj1ue2rcRTsApYCR50-gzGzoHsz',
        appKey: 'ATug9IScYQBHILhKWEqBHYxM',
      }
      
      const valine = new Valine(initData)
    }

    if (typeof Valine === 'function') initValine() 
    else getScript('https://cdn.jsdelivr.net/npm/valine/dist/Valine.min.js').then(initValine)
  }

  window.pjax ? loadValine() : window.addEventListener('load', loadValine)
})()</script><script>function subtitleType () {
  getScript('https://sdk.jinrishici.com/v2/browser/jinrishici.js').then(() => {
    jinrishici.load(function (result) {
      if (true) {
        var sub = "今日事&#44;今日畢,Never put off till tomorrow what you can do today".length == 0 ? new Array() : "今日事&#44;今日畢,Never put off till tomorrow what you can do today".split(',')
        var content = result.data.content
        var both = sub.unshift(content)
        var typed = new Typed('#subtitle', {
          strings: sub,
          startDelay: 300,
          typeSpeed: 150,
          loop: true,
          backSpeed: 50,
        })
      } else {
        document.getElementById('subtitle').innerHTML = result.data.content
      }
    })
  })
}

if (true) {
  if (typeof Typed === 'function') {
    subtitleType()
  } else {
    getScript('https://cdn.jsdelivr.net/npm/typed.js/lib/typed.min.js').then(subtitleType)
  }
} else {
  subtitleType()
}
</script></div><script src="https://cdn.jsdelivr.net/npm/blueimp-md5@2.17.0/js/md5.min.js"></script><script>window.addEventListener('load', () => {
  const changeContent = (content) => {
    if (content === '') return content

    content = content.replace(/<img.*?src="(.*?)"?[^\>]+>/ig, '[图片]') // replace image link
    content = content.replace(/<a[^>]+?href=["']?([^"']+)["']?[^>]*>([^<]+)<\/a>/gi, '[链接]') // replace url
    content = content.replace(/<pre><code>.*?<\/pre>/gi, '[代码]') // replace code
    content = content.replace(/<[^>]+>/g,"") // remove html tag

    if (content.length > 150) {
      content = content.substring(0,150) + '...'
    }
    return content
  }

  const getIcon = (icon, mail) => {
    if (icon) return icon
    let defaultIcon = '?d=robohash'
    let iconUrl = `https://gravatar.loli.net/avatar/${md5(mail.toLowerCase()) + defaultIcon}`
    return iconUrl
  }

  const generateHtml = array => {
    let result = ''

    if (array.length) {
      for (let i = 0; i < array.length; i++) {
        result += '<div class=\'aside-list-item\'>'

        if (true) {
          const name = 'data-lazy-src'
          result += `<a href='${array[i].url}' class='thumbnail'><img ${name}='${array[i].avatar}' alt='${array[i].nick}'></a>`
        }

        result += `<div class='content'>
        <a class='comment' href='${array[i].url}'>${array[i].content}</a>
        <div class='name'><span>${array[i].nick} / </span><time datetime="${array[i].date}">${btf.diffDate(array[i].date, true)}</time></div>
        </div></div>`
      }
    } else {
      result += '没有评论'
    }

    let $dom = document.querySelector('#card-newest-comments .aside-list')
    $dom.innerHTML= result
    window.lazyLoadInstance && window.lazyLoadInstance.update()
    window.pjax && window.pjax.refresh($dom)
  }

  const getComment = () => {
    const serverURL = 'https://cliyiuhj.lc-cn-n1-shared.com'

    var settings = {
      "method": "GET",
      "headers": {
        "X-LC-Id": 'ClIyIUhj1ue2rcRTsApYCR50-gzGzoHsz',
        "X-LC-Key": 'ATug9IScYQBHILhKWEqBHYxM',
        "Content-Type": "application/json"
      },
    }

    fetch(`${serverURL}/1.1/classes/Comment?limit=6&order=-createdAt`,settings)
      .then(response => response.json())
      .then(data => {
        const valineArray = data.results.map(function (e) {
          return {
            'avatar': getIcon(e.QQAvatar, e.mail),
            'content': changeContent(e.comment),
            'nick': e.nick,
            'url': e.url + '#' + e.objectId,
            'date': e.updatedAt,
          }
        })
        saveToLocal.set('valine-newest-comments', JSON.stringify(valineArray), 10/(60*24))
        generateHtml(valineArray)
      }).catch(e => {
        const $dom = document.querySelector('#card-newest-comments .aside-list')
        $dom.innerHTML= "无法获取评论，请确认相关配置是否正确"
      }) 
  }

  const newestCommentInit = () => {
    if (document.querySelector('#card-newest-comments .aside-list')) {
      const data = saveToLocal.get('valine-newest-comments')
      if (data) {
        generateHtml(JSON.parse(data))
      } else {
        getComment()
      }
    }
  }

  newestCommentInit()
  document.addEventListener('pjax:complete', newestCommentInit)
})</script><script defer="defer" id="ribbon" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/dist/canvas-ribbon.min.js" size="150" alpha="0.6" zIndex="-1" mobile="false" data-click="true"></script><script defer="defer" id="fluttering_ribbon" mobile="false" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/dist/canvas-fluttering-ribbon.min.js"></script></div></body></html>